#ifndef NANE_RENDERSYSTEM_H
#   define  NANE_RENDERSYSTEM_H

#   include "nane/RenderSystem/IRenderSystem.h"
#   include "nane/core/SubSystem.h"
#   include "nane/core/crt/FileSystem.h"

#   include "nane/RenderSystem/VertexBuffer.h"
#   include "nane/RenderSystem/IndexBuffer.h"
#   include "nane/RenderSystem/Texture.h"
#   include "nane/RenderSystem/ConstantBuffer.h"
#   include "nane/RenderSystem/VertexShader.h"
#   include "nane/RenderSystem/PixelShader.h"

namespace nane
{
    
    class RenderSystem
        : public SubSystem<IRenderSystem>
    {
    public:
        RenderSystem();
        ~RenderSystem();
        
    public:
        void Shutdown();
        
        bool InitializeContext( IWindow::OSHandle _windowHandle, uint32 _resWidth, uint32 _resHeight );
        
        VertexBuffer CreateVertexBuffer( EResourceUsage _usage, uint32 _verticesNum, uint32 _vertexSize
                                                , VertexElement* _elements, uint32 _elementsNum, byte* _initData );
        void SetVertexBuffer( uint16 _streamNumber, VertexBuffer& _vertexBuffer );
        
        IndexBuffer CreateIndexBuffer( EResourceUsage _usage, uint32 _indiciesNum, uint16* _initData );
        void SetIndexBuffer( IndexBuffer& _indexBuffer );
        
        Texture CreateTexture( EResourceUsage _usage, uint32 _width, uint32 _height, EPixelFormat _format );
        void SetTexture( uint32 _stage, Texture& _texture );
        
        bool BeginScene();
        void EndScene();
        void DrawPrimitive( EPrimitiveType _type, uint32 _startVertex, uint32 _primitiveCount );
        void DrawIndexedPrimitive( EPrimitiveType _type, uint32 _baseVertexIndex, uint32 _minIndex
                                         , uint32 _verticesNum, uint32 _startIndex, uint32 _primitiveCount );
        void ClearRenderTarget( EFrameBufferType _type, uint32 _color, float _depth, uint16 _stencil );
        void SwapBuffers();
        void SetProjectionMatrix( const float* _projection );
        void SetModelViewMatrix( const float* _modelview );
        void SetLightingEnable( bool _enable );
        void SetCullMode( ECullMode _mode );
        
        ConstantBuffer CreateConstantBuffer( uint32 _slots );

        VertexShader CreateVertexShader( const InputSeekablePtr& _input );
        void SetVertexShader( VertexShader& _vertexShader );
        void SetVertexShaderConstantBuffer( uint32 _slot, ConstantBuffer& _constantBuffer );
        
        PixelShader CreatePixelShader( const InputSeekablePtr& _input );
        void SetPixelShader( PixelShader& _pixelShader );
        void SetPixelShaderConstantBuffer( uint32 _slot, ConstantBuffer& _constantBuffer );
        
    public:
        class Implementation;
        Implementation* m;
    };
}   // namespace nane

#endif  // NANE_RENDERSYSTEM_H
